#ifndef UNDO_MANAGER_H
#define UNDO_MANAGER_H

#include <idocument.h>
#include <idocumentdata.h>

#include <QtCore/QObject>
#include <QtGui/QAction>
#include <QtGui/QUndoStack>

QT_BEGIN_NAMESPACE
class QUndoView;
QT_END_NAMESPACE

namespace core
{
class IPerspective;
}

namespace swp
{

class UndoManager : public QObject
{
    Q_OBJECT

public:
    static UndoManager* getInstance();
    static void destroy();

    void bindActions(QAction* undoAction, QAction* redoAction,
        QAction* undoMenuAction, QAction* redoMenuAction);
    void bindView(QUndoView* view);

private:
    UndoManager();
    ~UndoManager();

    void disableUndo();
    void disableRedo();
    void enableUndo();
    void enableRedo();

    void checkCapabilites(QUndoStack* stack);
    void switchStack(QUndoStack* stack);

signals:
    void currentStackCleared(const QSharedPointer<core::IDocument> document);

public slots:
    void createStack(core::IDocumentData* data);
    void destroyStack(core::IDocumentData* data);

    void clearStack(core::IDocumentData* data);

    void push(core::IDocumentData* data,
        QUndoCommand* command);

    void undo();
    void redo();

    void handlePerspectiveChange(core::IPerspective* perspective);
    void handleChangeOfDocument(core::IPerspective* perspective,
        const QSharedPointer<core::IDocument>& document);
    void handleDocumentSave(
        const QSharedPointer<core::IDocument>& document);

private:
    QAction* m_undoAction;
    QAction* m_undoMenuAction;
    QAction* m_redoAction;
    QAction* m_redoMenuAction;

    QUndoView* m_view;

    core::IPerspective* m_currentPerspective;
    core::IDocumentData* m_currentDataContext;
    QSharedPointer<core::IDocument> m_currentContext;

    QHash<core::IDocumentData*, QUndoStack*> m_stacks;
};

} // namespace swp

#endif
